import React, { Component } from 'react';
import { Upload, message, Button, Tooltip } from 'antd';
import type { UploadChangeParam, UploadFile } from 'antd/lib/upload/interface';
import numeral from 'numeral';
import styles from './index.less';
import classNames from 'classnames';
import SmartModal from '@/components/smartmodal';
import CropperC from 'react-cropper';

import { uploadFileApi } from '@/services/api';
import type { ProtoExtends } from '@/utils/utils';

const large = numeral(600);
const middle = numeral(large).multiply(0.4);
const small = numeral(middle).divide(6);

interface Cropper {
  getCroppedCanvas: () => {
    toBlob: (f: (b: Blob) => void) => void;
  };
}

const defaultProps = {
  onConfirm: function onConfirm() {},
  ratio: 1,
  cropperWidth: 320,
  shape: 'rectangle',
};

type DefaultProps = typeof defaultProps;

interface ImageSelectorProps {
  onConfirm: (img: any) => void;
  style?: React.CSSProperties;
  className?: string;
}

type Props = ProtoExtends<DefaultProps, ImageSelectorProps>;

/**
 * @param { function } onConfirm  点击确定按钮
 * @param { string } shape 预览形状
 */
export default class ImageSelectorCmp extends Component<Props> {
  static defaultProps = defaultProps;

  // static propTypes = {
  //   onConfirm: propTypes.func,
  //   ratio: propTypes.number,
  //   cropperWidth: propTypes.number,
  //   shape: propTypes.oneOf(['rectangle', 'circle']),
  // }

  state = {
    uploadFile: {} as UploadFile<any>,
    imageSrc: '',
    visible: false,
    sliderDisabled: true,
    uploading: false,
    modalWidth: 700,
    modalHeight: 500,
  };
  thisRef: unknown = null;
  cropper: Cropper = {
    getCroppedCanvas: () => ({
      toBlob: () => {},
    }),
  };

  constructor(props: Props) {
    super(props);

    this.closeModal = this.closeModal.bind(this);
    // this.handlerSizeChange = this.handlerSizeChange.bind(this);

    this.confirm = this.confirm.bind(this); // 确定
  }
  async confirm() {
    const { uploadFile } = this.state;
    if (!uploadFile) return;
    if (typeof this.cropper.getCroppedCanvas() === 'undefined') {
      return;
    }

    this.setState({
      uploading: true,
    });

    const { closeModal } = this;
    const { onConfirm } = this.props;
    const fileName = uploadFile.name;

    const blob: Blob = await new Promise((resolve) => {
      this.cropper.getCroppedCanvas().toBlob((b: Blob) => {
        resolve(b);
      });
    });

    const body = new FormData();

    body.append(fileName, blob);
    //把请求相关参数放入formData中
    body.append('tempFile', 'false');
    body.append('recTypeId', '0');
    body.append('recId', '0');
    body.append('subRecTypeId', '0');
    body.append('subRecId', '0');

    const ret = await uploadFileApi(body);
    onConfirm(ret.length === 1 ? ret[0] : ret);

    this.setState({
      uploading: false,
    });

    closeModal();
  }

  reset() {
    this.setState({
      uploadFile: null,
      imageSrc: '',
      sliderDisabled: true,
    });
  }

  closeModal() {
    this.setState({ visible: false });
  }

  render() {
    const { closeModal, confirm } = this;
    const { visible, imageSrc, uploadFile, uploading, modalWidth, modalHeight } = this.state;
    const { children, ratio, shape, style, className } = this.props;

    let cropperWidth;
    let cropperHeight;
    if (modalWidth - 150 >= (modalHeight - (41 + 45 + 20)) * ratio) {
      cropperHeight = modalHeight - (41 + 45 + 20);
      cropperWidth = cropperHeight * ratio;
    } else {
      cropperWidth = modalWidth - 150;
      cropperHeight = cropperWidth / ratio;
    }

    const uploadProps = {
      accept: 'image/*',
      showUploadList: false,
      className: styles.floatLeft,
      beforeUpload({ type }: { type: string }) {
        if (!/^image\//.test(type)) {
          message.error('请选择图片文件上传');
        }
        return false;
      },

      onChange({ file: originFile, fileList: list }: UploadChangeParam) {
        // 重置图片
        this.setState({
          uploadFile: originFile,
          imageSrc: URL.createObjectURL(originFile),
          sliderDisabled: false,
          scale: 1,
          visible: true,
        });
      },
      // ...this.props,
    };

    const footer = [
      <div key="footer">
        <Upload {...uploadProps}>
          <Button size="small">{tr('重新选择')}</Button>
        </Upload>
        <Button size="small" onClick={closeModal}>
          {tr('取消')}
        </Button>
        {uploadFile ? (
          <Button size="small" type="primary" onClick={confirm} loading={uploading}>
            {tr('确认')}
          </Button>
        ) : (
          <Tooltip title={tr('请选择上传的图片')}>
            <Button size="small" type="primary" disabled style={{ marginLeft: 8 }}>
              {tr('确认')}
            </Button>
          </Tooltip>
        )}
      </div>,
    ];

    return (
      <div style={style} className={className} ref={(thisRef) => (this.thisRef = thisRef)}>
        <Upload {...uploadProps}>{children}</Upload>
        <SmartModal
          id="ImageSelectorCmp"
          itemState={{
            height: modalHeight,
            width: modalWidth,
          }}
          title={tr('上传图片')}
          visible={visible}
          maskClosable={false}
          onCancel={closeModal}
          footer={footer}
          getContainer={this.thisRef}
          // onSizeChange={handlerSizeChange}
        >
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <CropperC
              style={{ height: cropperHeight, width: cropperWidth }}
              aspectRatio={ratio}
              viewMode={1}
              guides={false}
              src={imageSrc}
              ref={(cropper: Cropper) => (this.cropper = cropper)}
              preview=".preview"
            />
            <div style={{ width: 120, marginLeft: 10 }}>
              <div className={classNames('preview', styles.preview, shape === 'circle' && styles.circle)} />
              <p style={{ textAlign: 'center', color: '#bfbfbf' }}>{tr('预览')}</p>
            </div>
          </div>
        </SmartModal>
      </div>
    );
  }
}
